template<class SegNode, class TagNode>
struct LazySegTree {
	const int n;
	vector<SegNode> tr;
	vector<TagNode> tg;

	LazySegTree(int _n) : n(_n), tr(n * 4 + 1), tg(n * 4 + 1) {}
	LazySegTree(vector<SegNode> &init) : LazySegTree((int)init.size() - 1) {
		auto build = [&](auto &&self, int p, int l, int r) -> void {
			if (l == r) {
				tr[p] = init[l];
				return;
			}
			int m = (l + r) >> 1;
			self(self, p << 1, l, m);
			self(self, p << 1 | 1, m + 1, r);
			pull(p);
		};
		build(build, 1, 1, n);
	}

	inline void pull(int p) {
		tr[p] = tr[p << 1] + tr[p << 1 | 1];
	}

	inline void apply(int p, TagNode &v) {
		tr[p].apply(v);
		tg[p].apply(v);
	}

	inline void push(int p) {
		apply(p << 1, tg[p]);
		apply(p << 1 | 1, tg[p]);
		tg[p] = TagNode();
	}

	inline void modify(int p, int l, int r, int ql, int qr, TagNode& v) {
		if (l >= ql && r <= qr) {
			apply(p, v);
			return;
		}
		int m = (l + r) >> 1;
		push(p);
		if (ql <= m) {
			modify(p << 1, l, m, ql, qr, v);
		}
		if (qr > m) {
			modify(p << 1 | 1, m + 1, r, ql, qr, v);
		}
		pull(p);
	}

	inline void modify(int l, int r, TagNode& v) {
		modify(1, 1, n, l, r, v);
	}

	inline SegNode query(int p, int l, int r, int ql, int qr) {
		if (l >= ql && r <= qr) {
			return tr[p];
		}
		push(p);
		int m = (l + r) >> 1;
		if (ql <= m && qr > m) {
			return query(p << 1, l, m, ql, qr) + query(p << 1 | 1, m + 1, r, ql, qr);
		} else if (ql <= m) {
			return query(p << 1, l, m, ql, qr);
		} else {
			return query(p << 1 | 1, m + 1, r, ql, qr);
		}
	}

	inline SegNode query(int l, int r) {
		return query(1, 1, n, l, r);
	}
};

struct TagNode {
	Mint tga = 0, tgb = 0;

	void apply(TagNode &t) {
		tga += t.tga;
		tgb += t.tgb;
	}
};
struct SegNode {
	Mint suma = 0, sumb = 0, sumv = 0;
	int sz = 1;

	void apply(TagNode &t) {
		sumv += t.tga * sumb;
		suma += t.tga * sz;
		sumv += t.tgb * suma;
		sumb += t.tgb * sz;
	}
};

SegNode operator+(SegNode lhs, SegNode rhs) {
	SegNode t;
	t.suma = lhs.suma + rhs.suma;
	t.sumb = lhs.sumb + rhs.sumb;
	t.sumv = lhs.sumv + rhs.sumv;
	t.sz = lhs.sz + rhs.sz;
	return t;
};
int a[N], b[N];
void solve()
{
	int n, q;
	cin >> n >> q;

	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	for (int i = 1; i <= n; i++) {
		cin >> b[i];
	}

	vector<SegNode> c(n + 1);
	for (int i = 1; i <= n; i++) {
		c[i] = SegNode{a[i], b[i], Mint(1ll * a[i] * b[i]), 1};
	}
	LazySegTree<SegNode, TagNode> tr(c);
	while (q--) {
		int op, l, r, x;
		cin >> op >> l >> r;
		TagNode t;
		if (op == 1) {
			cin >> x;
			t = {x, 0};
			tr.modify(l, r, t);
		} else if (op == 2) {
			cin >> x;
			t = {0, x};
			tr.modify(l, r, t);
		} else {
			cout << tr.query(l, r).sumv << '\n';
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr), cout.tie(nullptr);
	int _ = 1;
	// cin >> _;
	while (_--) {
		solve();
	}
	return 0;
}